﻿/*
Copyright (c) 2010, hiSoft
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the hiSoft nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE HISOFT AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL HISOFT BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.IO;
using Selenium;
using System.Diagnostics;

namespace Orchard.Test.Library
{
    public class TestLibrary
    {
        #region user define type

        public UserHelper UserHelper { get; private set; }
        public MediaHelp MediaHelp { get; private set; }
        public BlogHelper BlogHelper { get; private set; }
        public CommentHelper CommentHelper { get; private set; }
        public ContentItemHelper ContentItemHelper { get; private set; }
        public ThemeHelper ThemeHelper { get; private set; }
        public PageHelper PageHelper { get; private set; }
        public RoleHelper RoleHelper { get; private set; }
        public TagHelper TagHelper { get; private set; }
        public ModuleHelper ModuleHelper { get; private set; }
        public ContentTypeHelper ContentTypeHelper { get; private set; }
        public SearchHelper SearchHelper { get; private set; }
        public LocalizationHelper LocalizationHelper { get; private set; }
        public SettingHelp SettingHelper { get; private set; }
        public NavigationHelper NavigationHelper { get; private set; }
        public MultiTenancyHelper MultiTenancyHelper { get; private set; }
        public SetupHelper SetupHelper { get; private set; }
        public PackagingHelper PackagingHelper { get; private set; }
        public WebCommandLineHelper WebCommandLineHelper { get; private set; }
        public OrchardExeHelper OrchardExeHelper { get; private set; }
        public WidgetHelper WidgetHelper { get; private set; }
        public ListHelper ListHelper { get; private set; }
        public ListItemHelper ListItemHelper { get; private set; }
        public ImportExportHelper ImportExportHelper { get; private set; }
        public WarmupHelper WarmupHelper { get; private set; }
        public MessagesHelper MessagesHelper { get; private set; }
        public LiveWriterHelper LiveWriterHelper { get; private set; }

        public Blog DefaultBlog { get; private set; }
        public Post DefaultPost { get; private set; }
        public Page DefaultPage { get; private set; }
        public Role DefaultRole { get; private set; }
        public User DefaultUser { get; private set; }
        public Tenant DefaultTenant { get; private set; }

        public List<Char> SpecialCharactersForSlug { get; private set; }

        public List<Char> InvalidCharsForMediaFolder { get; private set; }

        public ISelenium Selenium { get; private set; }

        public string SiteUrl { get; private set; }

        public static StringBuilder StrExistExceptionMessage =new StringBuilder("");

        public enum DBType
        {
            SQLCE = 1,
            SQLServer = 2
        };              

        public class Consts
        {
            public const string TimeToWaitForPageToLoad = "30000";

            public const string LongTimeToWaitForPageToLoad = "120000";

            public const string AdminUserName = "admin";

            public const string DefaultUserName = "DefaultUser";

            public const string CommonPassword = "0123456";

            public const string ScriptString = "<script>alert(\"Hello World\")</script>";

            public const string StrWithEnter = "Hello" + "\r" + "World";

            public const string DefaulBlogUrl_Writer = "http://localhost/default-test-blog";

            public const string StrOf255Chars = "a23456789022345678903234567890423456789052345678906234567890723456789082345678909234567890023456710012345678902234567890323456789042345678905234567890623456789072345678908234567890923456789002345672001234567890223456789032345678904234567890523456789062255";

            public const string StrOf256Chars = "a234567890223456789032345678904234567890523456789062345678907234567890823456789092345678900234567100123456789022345678903234567890423456789052345678906234567890723456789082345678909234567890023456720012345678902234567890323456789042345678905234567890623256";

            public const string StrExamplePictureUrl = "http://ww1.sinaimg.cn/large/63465b78jw1dgnkma2i8dj.jpg";  //this picture size:435px × 446px


            public const string StrExampleParticalModuleId = "CyberStride.Contacts";

            public const string StrExampleModuleName = "Contact Form";        

            public const string StrExampleThemeName = "Dark";

            public const string StrExampleThemeId = "Orchard.Theme.Dark";

            public const string StrExampleThemeVersion = "1.0.22";

            public const string StrSetupErrorInfo = "Setup Test Exception !!!";

            public const string StrDelInstalledModuleError = "Try to delete temp module occur error.";

            public const string StrExamplePackageId = "Szmyd.Orchard.Modules.Menu";  //Locate:D:\Workspace\orchard.test\Orchard.Test\TestData\ModuleResource //need update when changed

            public const string StrExamplePackageVersion = "1.3.0";

            public const string StrExamplePackageNameInWebCmd = "Orchard.Indexing";

            public const string StrExamplePackageVersionInWebCmd = "1.2.0";


            public const string StrOfStartWithSpecialChar = "$23456";

            public const string StrOfStartWithNumricChar = "123456";


            public const string strPageNextLocator = "link=>";  // //a[contains(text(),'>')]
            public const string strPagePrevLocator = "link=<";
            public const string strPageFirstLocator = "link=<<"; //  //a[contains(text(),'>>')]
            public const string strPageLastLocator = "link=>>";  //  //a[contains(text(),'<<')]

            public const string strSenderUserNameOf163 = "orchardqa";
            public const string strSenderEmailAddOf163 = "orchardqa@163.com";
            public const string strSenderEamilPwdOf163 = "0123456@H!";
            public const string strEmailSMTPHostOf163 = "smtp.163.com";
            public const string strRegisterUserNameOf163 = "orchard_User";
            public const string strRegisterUserEmailOf163 = "orchard_User@163.com";
            public const string strLostPwdUserNameOf163 = "orchard_LostPwd";
            public const string strLostPwdUserEmailOf163 = "orchard_LostPwd@163.com";
            public const string strUser1Nameof163 = "orchard_user1";
            public const string strUser1Emailof163 = "orchard_user1@163.com";
            public const string strUser2Nameof163 = "orchard_user2";
            public const string strUser2Emailof163 = "orchard_user2@163.com";
            public const string strUser3Nameof163 = "orchard_user3";
            public const string strUser3Emailof163 = "orchard_user3@163.com";
            public const string strWebsiteNameForValidateMail = "Hisoft Orchard CMS";
            public const string strContactUsUserNameOf163 = "orchard_contactus";
            public const string strContactUsEmailOf163 = "orchard_contactus@163.com";


            #region Required to modify value according to different environment.

            public const string SQLServerInstance = ".\\sqlexpress";

            public const string DefaultOrchardSite = "http://localhost";

            public const string DefaultWorkSpace = @"D:\WorkSpace";

            public const string DataDrivenPath = @"D:\Workspace\Orchard.Test\Orchard.Test\TestData";

            #endregion

            public static readonly string SeleniumHost;

            public static readonly int SeleniumPort;

            public static readonly string Browser;

            public static readonly string SecondBrowser;

            public static readonly string OrchardSite;

            public static readonly string WorkSpace = DefaultWorkSpace;

            static Consts()
            {
                var value = Environment.GetEnvironmentVariable("ORCHARDSITE");
                OrchardSite = String.IsNullOrEmpty(value) ? DefaultOrchardSite : value;
                value = Environment.GetEnvironmentVariable("SELENIUMPORT");
                SeleniumPort = String.IsNullOrEmpty(value) ? 4444 : Int32.Parse(value);
                value = Environment.GetEnvironmentVariable("SELENIUMHOST");
                SeleniumHost = String.IsNullOrEmpty(value) ? "localhost" : value;
                value = Environment.GetEnvironmentVariable("BROWSERMODE");
                Browser = String.IsNullOrEmpty(value) ? "*firefox" : value;
                value = Environment.GetEnvironmentVariable("SECONDBROWSER");
                SecondBrowser = String.IsNullOrEmpty(value) ? "*googlechrome" : value;
                value = Environment.GetEnvironmentVariable("ROOT");
                WorkSpace = String.IsNullOrEmpty(value) ? DefaultWorkSpace : value;
            }

            public static readonly string OrchardSrcPath = String.Format(@"{0}\Orchard\src", WorkSpace);
            public static readonly string OrchardWebPath = String.Format(@"{0}\Orchard.Web", OrchardSrcPath);
            public static readonly string OrchardModulesPath = String.Format(@"{0}\Modules", OrchardWebPath);
            public static readonly string OrchardBackUpModulesPath = String.Format(@"{0}\_Backup", OrchardModulesPath);
            public static readonly string OrchardThemesPath = String.Format(@"{0}\Themes", OrchardWebPath);
            public static readonly string OrchardAppDataPath = String.Format(@"{0}\App_Data", OrchardWebPath);
            public static readonly string OrchardAppDataSitesPath = String.Format(@"{0}\Sites", OrchardAppDataPath);
            public static readonly string OrchardAppDataExportsPath = String.Format(@"{0}\Exports", OrchardAppDataPath);
            public static readonly string OrchardTestDataPath = String.Format(@"{0}\Orchard.Test\Orchard.Test\TestData", WorkSpace);

            public static string[] whitespaceChars = new string[] {
                     char.ConvertFromUtf32(9),
                     char.ConvertFromUtf32(10),
                     char.ConvertFromUtf32(11),
                     char.ConvertFromUtf32(12),
                     char.ConvertFromUtf32(13),
                     char.ConvertFromUtf32(32),
                     char.ConvertFromUtf32(133),
                     char.ConvertFromUtf32(160),
                     char.ConvertFromUtf32(5760),
                     char.ConvertFromUtf32(8192),
                     char.ConvertFromUtf32(8193),
                     char.ConvertFromUtf32(8194),
                     char.ConvertFromUtf32(8195),
                     char.ConvertFromUtf32(8196),
                     char.ConvertFromUtf32(8197),
                     char.ConvertFromUtf32(8198),
                     char.ConvertFromUtf32(8199),
                     char.ConvertFromUtf32(8200),
                     char.ConvertFromUtf32(8201),
                     char.ConvertFromUtf32(8202),
                     char.ConvertFromUtf32(8203),
                     char.ConvertFromUtf32(8232),
                     char.ConvertFromUtf32(8233),
                     char.ConvertFromUtf32(12288),
                     char.ConvertFromUtf32(65279)
         };
        
        }

        #endregion
        

        public TestLibrary(ISelenium selenium)
        {
            this.UserHelper = new UserHelper(this);
            this.BlogHelper = new BlogHelper(this);
            this.MediaHelp = new MediaHelp(this);
            this.ModuleHelper = new ModuleHelper(this);
            this.CommentHelper = new CommentHelper(this);
            this.ContentItemHelper = new ContentItemHelper(this);
            this.ThemeHelper = new ThemeHelper(this);
            this.PageHelper = new PageHelper(this);
            this.RoleHelper = new RoleHelper(this);
            this.TagHelper = new TagHelper(this);
            this.SearchHelper = new SearchHelper(this);
            this.ContentTypeHelper = new ContentTypeHelper(this);
            this.MultiTenancyHelper = new MultiTenancyHelper(this);
            this.LocalizationHelper = new LocalizationHelper(this);
            this.SettingHelper = new SettingHelp(this);
            this.NavigationHelper = new NavigationHelper(this);
            this.SetupHelper = new SetupHelper(this);
            this.PackagingHelper = new PackagingHelper(this);
            this.WebCommandLineHelper = new WebCommandLineHelper(this);
            this.WidgetHelper = new WidgetHelper(this);
            this.OrchardExeHelper = new OrchardExeHelper();
            this.ListHelper = new ListHelper(this);
            this.ListItemHelper = new ListItemHelper(this);
            this.ImportExportHelper = new ImportExportHelper(this);
            this.WarmupHelper = new WarmupHelper(this);
            this.MessagesHelper = new MessagesHelper(this);
            this.LiveWriterHelper = new LiveWriterHelper(this);

            Selenium = selenium;
            InitialDefaultSiteDate();
        }

        private void InitialDefaultSiteDate()
        {
            var blogSetting = new BlogSettings();
            blogSetting.Title = "Default Test Blog";
            blogSetting.Permalink = "default-test-blog";
            blogSetting.MenuText = blogSetting.Title;
            DefaultBlog = new Blog(this, blogSetting);

            DefaultPost = new Post(new PostSettings()
            {
                Title = "Default Test Post",
                Permalink = "default-test-post",
                Body = "This is for orchard web site testing purpose.",
                Tags = new List<Tag> { new Tag("Orchard Test", null) },
                PublishSetting = PublishSettings.PublishNow
            },
            DefaultBlog);

            DefaultPage = new Page(new PageSettings()
            {
                Title = "Default Test Page",
                Permalink = "default-test-page",
                MenuText = "Default Test Page"
            });

            DefaultRole = new Role(this, "DefaultRole");

            DefaultUser = new User
            (
                new UserSettings()
                {
                    UserName = Consts.DefaultUserName,
                    Email = "DefaultUser@microsoft.com",
                    Password = Consts.CommonPassword,
                    Roles = new List<Role>() { DefaultRole }
                }
            );

            DefaultTenant = new Tenant("alpha", "alpha.127-0-0-1.org.uk", DataBaseSetup.BuiltIn);

            SpecialCharactersForSlug = new List<char>();
            SpecialCharactersForSlug.Add(':');
            SpecialCharactersForSlug.Add('?');
            SpecialCharactersForSlug.Add('#');
            SpecialCharactersForSlug.Add('[');
            SpecialCharactersForSlug.Add(']');
            SpecialCharactersForSlug.Add('@');
            SpecialCharactersForSlug.Add('!');
            SpecialCharactersForSlug.Add('$');
            SpecialCharactersForSlug.Add('&');
            SpecialCharactersForSlug.Add('\'');
            SpecialCharactersForSlug.Add('(');
            SpecialCharactersForSlug.Add(')');
            SpecialCharactersForSlug.Add('*');
            SpecialCharactersForSlug.Add('+');
            SpecialCharactersForSlug.Add(',');
            SpecialCharactersForSlug.Add(';');
            SpecialCharactersForSlug.Add('=');
            SpecialCharactersForSlug.Add('<');
            SpecialCharactersForSlug.Add('>');
            SpecialCharactersForSlug.Add('\\');
            SpecialCharactersForSlug.Add(' ');

            InvalidCharsForMediaFolder = new List<char>();
            InvalidCharsForMediaFolder.Add('/');
            InvalidCharsForMediaFolder.Add('\\');
            InvalidCharsForMediaFolder.Add('?');
            InvalidCharsForMediaFolder.Add('*');
            InvalidCharsForMediaFolder.Add('<');
            InvalidCharsForMediaFolder.Add('>');
            InvalidCharsForMediaFolder.Add('|');
        }

        public static TestLibrary SetupTest()
        {
            return SetupTest(true);
        }

        public static TestLibrary SetupTest(string objectClassName)
        {
            TestLibrary testlibrary=null;
            try
            {
                testlibrary = SetupTest(true);
            }
            catch (Exception ex)
            {
                TestLibrary.WriteErrorInfoToLog(LogCategory.SetupTest, objectClassName, "outerPeriod", TestLibrary.Consts.StrSetupErrorInfo + ex.ToString());
            }
            if (StrExistExceptionMessage.Length > 1)
            {
                TestLibrary.WriteErrorInfoToLog(LogCategory.SetupTest, objectClassName, "Outer_TotalMessages", StrExistExceptionMessage.ToString());
            }
         
            return testlibrary;
           
        }

        public static TestLibrary SetupTest(bool copyDefaultSites)
        {
            return SetupTest(copyDefaultSites, Consts.SeleniumHost, Consts.SeleniumPort, Consts.Browser, Consts.OrchardSite);
            //return SetupTest(DBType.SQLServer, copyDefaultSites, Consts.SeleniumHost, Consts.SeleniumPort, Consts.Browser, Consts.OrchardSite); 
        }

        public static TestLibrary SetupTest(bool copyDefaultSites, string seleniumHost, int seleniumPort, string browser, string orchardSite)
        {
          
                ClearMedia();
                ClearAppData();          
           
                if (copyDefaultSites)
                {
                    CopyDirectory(String.Format(@"{0}\Orchard.Test\Sites\Sites", TestLibrary.Consts.WorkSpace), TestLibrary.Consts.OrchardAppDataSitesPath);
                }

                return SetupTest(seleniumHost, seleniumPort, browser, orchardSite);                
            
        }

        public static TestLibrary SetupTest(string seleniumHost, int seleniumPort, string browser, string orchardSite)
        {
            var selenium = new DefaultSelenium(seleniumHost, seleniumPort, browser, orchardSite);
            selenium.Start();
            return new TestLibrary(selenium) { SiteUrl = orchardSite };
        }

        public static TestLibrary SetupTestOnSecondBrowser()
        {            
              return SetupTest(Consts.SeleniumHost, Consts.SeleniumPort, Consts.SecondBrowser, Consts.OrchardSite);          
        }

        public static TestLibrary SetupTest(DBType dbtype, bool copyDefaultSites, string seleniumHost, int seleniumPort, string browser, string orchardSite)
        {
            ClearMedia();

            if (dbtype == DBType.SQLServer)
            {

                ClearAppData(dbtype);

            }
            else
            {
                ClearAppData();
                if (copyDefaultSites)
                {
                    CopyDirectory(String.Format(@"{0}\Orchard.Test\Sites\Sites", TestLibrary.Consts.WorkSpace), TestLibrary.Consts.OrchardAppDataSitesPath);
                }
            }
            return SetupTest(seleniumHost, seleniumPort, browser, orchardSite);
        }

        public void ClickAndWait(string locator)
        {
            Selenium.Click(locator);
            Selenium.WaitForPageToLoad(TestLibrary.Consts.TimeToWaitForPageToLoad);
        }

        public void ShutDown()
        {
            Selenium.Stop();
        }

        private static void ClearMedia()
        {
            string mediaPath = String.Format(@"{0}\Media\Default", TestLibrary.Consts.OrchardWebPath);
            if (Directory.Exists(mediaPath))
            {
                Directory.Delete(mediaPath, true);
            }
        }

        /// <summary>
        /// Clear and cover the data when we use sql server to run the full test pass
        /// </summary>
        /// <param name="dbtype"></param>
        private static void ClearAppData(DBType dbtype)
        {

            DataTable dtAllTables = new DataTable();

            CopyAndCoverTables copyAndCoverTables = new CopyAndCoverTables();
            dtAllTables = copyAndCoverTables.GetTables(CopyAndCoverTables.TableType.AllTables);

            //without copy the table ,then we copy them
            if (dtAllTables.Rows.Count == copyAndCoverTables.GetTables(CopyAndCoverTables.TableType.OldTables).Rows.Count)
            {
                copyAndCoverTables.CopyTable();
            }


            //Delete the tables create by setup module 
            if (copyAndCoverTables.DeleteOldTables() == 0)
            {
                return;
            }

            //Cover the tables
            if (copyAndCoverTables.RecoverTable() == 0)
            {
                return;
            }
        }

        private static void ClearAppData()
        {          
            string hrestartPath = String.Format(@"{0}\hrestart.txt", TestLibrary.Consts.OrchardAppDataPath);
            string cachePath = String.Format(@"{0}\cache.dat", TestLibrary.Consts.OrchardAppDataPath);
                        
            string message = "";
            System.Diagnostics.Process pro = new System.Diagnostics.Process();
            try
            {               
                for (int i = 0; i < 6; i++)
                {
                    if (File.Exists(hrestartPath))
                    {
                        File.Delete(hrestartPath);
                    }
                    if (File.Exists(cachePath))
                    {
                        File.Delete(cachePath);
                    }
                    if (Directory.Exists(TestLibrary.Consts.OrchardAppDataSitesPath))
                    {
                        try { Directory.Delete(TestLibrary.Consts.OrchardAppDataSitesPath, true); }
                        catch (Exception ex)
                        { if (i == 5) throw ex; }
                    }
                    else break;
                }
            }
            catch (Exception exx)
            {
                WriteErrorInfoToLog(LogCategory.ClearAppData,"", "AfterDeleteAppData6Times", exx.ToString());
                StrExistExceptionMessage.AppendLine("AfterDeleteAppData6Times");
                StrExistExceptionMessage.AppendLine(exx.ToString());
                ProcessStartInfo proStartInfo = new ProcessStartInfo("iisreset.exe");
                proStartInfo.UseShellExecute = false;
                proStartInfo.RedirectStandardOutput = true;
                proStartInfo.RedirectStandardError = true;
                pro.StartInfo = proStartInfo;
                try
                {
                    pro.Start();
                    StreamReader myStreamReader = pro.StandardOutput;
                    StreamReader myStreamReader2 = pro.StandardOutput;
                    message = myStreamReader.ReadToEnd();
                    WriteErrorInfoToLog(LogCategory.ClearAppData, "", "StartIISReset", message);
                    StrExistExceptionMessage.AppendLine("StartIISReset");
                    StrExistExceptionMessage.AppendLine(message);
                    pro.WaitForExit();
                }
                catch (Exception ex)
                {
                    WriteErrorInfoToLog(LogCategory.ClearAppData, "", "InProcessOfIISReset", ex.ToString());
                    StrExistExceptionMessage.AppendLine("InProcessOfIISReset");
                    StrExistExceptionMessage.AppendLine(ex.ToString());
                }
            }
            finally
            {                    
                pro.Close();
                if (File.Exists(hrestartPath))
                {
                    File.Delete(hrestartPath);
                }
                if (File.Exists(cachePath))
                {
                    File.Delete(cachePath);
                }

                for (int j = 0; j < 4; j++)
                {
                    if (Directory.Exists(TestLibrary.Consts.OrchardAppDataSitesPath))
                    {
                        try { Directory.Delete(TestLibrary.Consts.OrchardAppDataSitesPath, true); }
                        catch (Exception ex)
                        {
                            KillProcess("Orchard");
                            if (j == 2)
                            {
                                WriteErrorInfoToLog(LogCategory.ClearAppData, "", "DeleteAppDataAfterIISReset", ex.ToString());
                                StrExistExceptionMessage.AppendLine("DeleteAppDataAfterIISReset");
                                StrExistExceptionMessage.AppendLine(ex.ToString());
                            }
                        }
                    }
                    else break;
                } 
            }
          
        }

        public static void WriteErrorInfoToLog(string message)
        {
            WriteErrorInfoToLog(LogCategory.None,"", "",message);
        }

        public static void WriteErrorInfoToLog(string strFileName,string message)
        {
            WriteErrorInfoToLog(LogCategory.None,strFileName, "", message);
        }

        public static void WriteErrorInfoToLog(LogCategory logCategory,string ErrorFileName,string strPeriod,string message)
        {
            string path = String.Format(@"{0}\orchard.test", TestLibrary.Consts.WorkSpace);
            string pa = path + "\\ExceptionLogs\\" + DateTime.Now.Year.ToString() + "\\" + DateTime.Now.Month.ToString();
            string log = pa + "\\" + DateTime.Now.Day.ToString() + ".txt";
            if (!Directory.Exists(pa))
            {
                Directory.CreateDirectory(pa);
            }
            if (!File.Exists(log))
                File.Create(log).Close();
            using (StreamWriter w = File.AppendText(log))
            {
                w.WriteLine("<message>");
                w.WriteLine("<datetime>DateTime: {0} </datetime>", DateTime.Now);
                w.WriteLine("<machine>Machine: {0}</machine>", Environment.MachineName); 
                w.WriteLine("<category>Category: {0}</category>", logCategory.ToString());
                w.WriteLine("<position>Position: {0}</position>",ErrorFileName);
                w.WriteLine("<period>Period: {0}</period>", strPeriod);
                w.WriteLine("<details>DetailsMessage: {0}</details>",message);
                w.WriteLine("</message>");
                w.WriteLine();
                w.Flush();
                w.Close();
            }
        }

        private static void KillProcess(string processName)
        {
            Process myproc = new Process();
            //get all opening processes
            Process[] processes = Process.GetProcesses();
            for (int i = 0; i <= processes.Length - 1; i++)
            {
                if (processName == processes[i].ProcessName.ToString())
                {
                    try
                    {
                        foreach (Process thisproc in Process.GetProcessesByName(processName))
                        {                          
                                thisproc.Kill();                           
                        }
                       WriteErrorInfoToLog("Kill " + processName + ".exe Successfully！");
                       break;
                    }
                    catch (Exception e)
                    {
                        WriteErrorInfoToLog("Kill " + processName + ".exe Failed！"+e.ToString());
                    }
                }
            }
        }

        private static void CopyDirectory(string srcDir, string dstDir)
        {
            CopyDirectory(srcDir, dstDir, true);
        }

        private static void CopyDirectory(string srcDir, string dstDir,bool allowOverWriteFile)
        {
            if (dstDir[dstDir.Length - 1] != Path.DirectorySeparatorChar)
            {
                dstDir += Path.DirectorySeparatorChar;
            }

            if (!Directory.Exists(dstDir))
            {
                Directory.CreateDirectory(dstDir);
            }

            string[] files = Directory.GetFileSystemEntries(srcDir);
            foreach (string element in files)
            {
                // Sub directories
                if (Directory.Exists(element))
                {
                    CopyDirectory(element, dstDir + Path.GetFileName(element),allowOverWriteFile);
                }
                // Files in directory
                else
                {                   
                    File.Copy(element, dstDir + Path.GetFileName(element), allowOverWriteFile);
                }
            }
        }

        public static void CopySitesFolder(string srcDir, string dstDir)
        {
            CopyDirectory(srcDir, dstDir,false);           
        }

        public string GetScheduledDateString(DateTime dateTime)
        {
            return String.Format("{0}/{1}/{2}", dateTime.Month, dateTime.Day, dateTime.Year);
        }

        public string GetScheduledTimeString(DateTime dateTime)
        {
            return String.Format("{0}:{1} {2}", dateTime.Hour % 12, dateTime.Minute, (dateTime.Hour / 12 == 0 ? "AM" : "PM"));
        }

       
        /// <summary>
        /// 日志类型
        /// </summary>
        public enum LogCategory
        {         
            ClearAppData,        
            SetupTest,       
            RPF_LiveWriter,         
            Packaging_Module,
            Packaging_Theme,
            None 
        }
           


    }
}
